# ifndef DEF_SOURCE
# define DEF_SOURCE

class Game;
class Module;
class Renderer;
class GUI;
class AI;
class EventListener;

class World;
class Map;
class Obstacle;
class ObjectAction;
class ObjectConnect;
class Chest;
class ObjectPickUp;

class Personage;

class Hero;
class Equipment;
class Inventory;
class ObjectInventory;
class Armor;
class Weapon;
class Shield;
class Jewel;
class Quests;

class Enemy;
class PNJ;

# define ONE 1
# define TWO 2

# define RIEN 0
# define CREATE_MENU 1
# define MENU 2
# define NEW_GAME 3
# define GAME 4
# define MOUSE_LEFT_CLICKED 5
# define QUIT 6
# define CREATE_GAME_MENU 7
# define GAME_MENU 8
# define RETURN_GAME 9
# define RETURN_MENU 10
# define GAME_INVENTORY 11
# define OPEN_COMPETENCE 12
# define OPEN_INVENTORY 13
# define CLOSE_INVENTORY 14
# define CLOSE_COMPETENCE 15
# define REQUEST 16
# define OPEN_TALK 17
# define CLOSE_GUI_WINDOW 18
# define CLOSE_TALK 19
# define OPEN_QUEST 20
# define CLOSE_QUEST 21
# define HERO_DEATH 22

# define SHEET_BASE CEGUI::String( "GameOfTheYear/")
# define SHEET_MENU CEGUI::String( "Menu/")
# define SHEET_GAME CEGUI::String( "Game/")
# define SHEET_GAME_MENU CEGUI::String( "GameMenu/")
# define SHEET_GAME_DEATH CEGUI::String( "GameDeath/")
# define SHEET_GAME_INVENTORY CEGUI::String( "GameInventory/")
# define SHEET_GAME_COMPETENCE CEGUI::String( "GameCompetence/")
# define SHEET_GAME_QUEST CEGUI::String( "GameQuest/")
# define SHEET_GAME_TALK CEGUI::String( "GameTalk/")

# define LUA_WEAPONS "Resources/Lua/Weapons.lua"
# define LUA_ARMORS "Resources/Lua/Armors.lua"
# define LUA_SHIELDS "Resources/Lua/Shields.lua"
# define LUA_OBJECT_ACTION "Resources/Lua/ObjectAction.lua"
# define LUA_NAV_MESH "Resources/Lua/NavMesh.lua"

enum QueryFlag
{
	GROUND_FLAG = 1 << 0,
	ENEMY_FLAG = 1 << 1,
	ME_FLAG = 1 << 2,
	PNJ_FLAG = 1 << 3,
	DEATH_FLAG = 1 << 4,
	WALL_FLAG = 1 << 5,
	ACTION_FLAG = 1 << 6
};

enum ActionType
{
	CONNECT_MAP,
	CHEST,
	OBJECT
};

# define HEAD_ARMOR 0
# define BODY_ARMOR 1
# define ARMS_ARMOR 2
# define HIPS_ARMOR 3
# define FEET_ARMOR 4
# define SHIELD 5
# define SWORD 6
# define AXE 7
# define RING 8
# define NECKLACE 9
# define POTION 10

enum Action
{
	NOTHING,
	GO,
	GO_HIT,
	GO_TALK,
	GO_ACTION,
	HIT,
	TALK,
	ACTION
};

# define NORMAL 0
# define ACTIVE_QUEST 1
# define NEXT_STEP_QUEST 2
# define QUIT_DIALOG 3

# define QUEST_KILL 0
# define QUEST_TALK 1

enum State
{
	MENU_STATE,
	GAME_STATE,
	GUI_STATE
};

# include <queue>
# include <stack>
# include <sstream>
# include <map>
# include <vector>
# include <string>

# include <OGRE\OgreRoot.h>
# include <OGRE\OgreConfigFile.h>
# include <OGRE\OgreRenderWindow.h>
# include <OGRE\OgreSceneManager.h>
# include <OGRE\OgreCamera.h>
# include <OGRE\OgreViewport.h>
# include <OGRE\OgreFrameListener.h>
# include <OGRE\OgreWindowEventUtilities.h>
# include <OGRE\OgreEntity.h>
# include <OGRE\OgreSceneNode.h>
# include <OGRE\OgreMeshManager.h>
# include <OGRE\OgreRay.h>

# include <OIS\OISEvents.h>
# include <OIS\OISInputManager.h>
# include <OIS\OISKeyboard.h>
# include <OIS\OISMouse.h>

# include <CEGUI.h>
# include <RendererModules\Ogre\CEGUIOgreRenderer.h>

# include <Lua/lua.hpp>

struct Event
{
	unsigned int message;

	float x;
	float y;
};

struct Damage
{
	unsigned int strength;
	unsigned int damage;
};

struct Experience
{
	unsigned int experience;
	unsigned int level;
};

struct PieceDialog
{
	unsigned int action;
	std::string pnjTalk;
	
	std::string* questName;

	std::deque<std::string*> answers;
	std::deque<std::string*> destinations;
};

struct Quest
{
	std::string name;
	std::string description;
	std::vector<int> actions;
	std::vector<std::string*> targets;
	std::vector<std::string*> descriptions;
	int current;

	unsigned int rewardExp;
	std::vector<std::string*> rewardObject;
	std::vector<std::string*> rewardQuests;
};

struct NavMeshPol
{
	unsigned int number;
	
	std::vector<Ogre::Vector2> points;
	Ogre::Vector2 middle;

	std::vector<NavMeshPol*> neighbors;
	std::vector<int> distances;
	std::vector<Ogre::Vector2> neighborPoint1;
	std::vector<Ogre::Vector2> neighborPoint2;
	std::vector<Ogre::Vector2> neighborMidPoint;
};

struct Node
{
	Node* previous;

	NavMeshPol* current;
	NavMeshPol* previousNavMesh;

	int weightBefore;
	int weightAfter;
	int weightTotal;
};

// TEMPORARY

# define INCREMENT 100

# endif